package com.huawei.spare.part.replace.framework;

import com.google.common.collect.Lists;
import com.huawei.spare.part.replace.Constants;
import com.huawei.spare.part.replace.models.Configs;
import com.huawei.spare.part.replace.models.Project;
import com.huawei.spare.part.replace.models.Replacement;
import com.huawei.spare.part.replace.utils.Application;
import com.huawei.spare.part.replace.utils.JsonMapper;
import com.huawei.spare.part.replace.views.dashboard.DashboardView;
import io.reactivex.Observable;
import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
import io.reactivex.schedulers.Schedulers;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import lombok.Data;

import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.concurrent.Callable;

/**
 * 数据总线
 */
@Data
public class SmartDataBus {

    private static SmartDataBus instance;

    Stage stage;
    DashboardView dashboard;
    ResourceBundle bundle;      // global resource bundle

    Configs configs = new Configs();    // application configs
    Project project = new Project();    // prepare project instance
    Boolean autoLoad = false;
    Replacement replacement = new Replacement();


    private SmartDataBus() {
        init();
    }

    public static SmartDataBus get() {
        if (instance == null) {
            synchronized (SmartDataBus.class) {
                if (instance == null) {
                    instance = new SmartDataBus();
                }
            }
        }
        return instance;
    }

    /**
     * initial data bus
     */
    private void init() {
        // load bundle
        bundle = ResourceBundle.getBundle(Constants.DefaultBundleName, Locale.getDefault());
        // other async init tasks
        Observable.defer((Callable<Observable<Configs>>) () -> {
//            final File configFile = new File(Application.getConfigFileInputStream());
//            final String configFileContent = FileUtils.readFileToString(configFile, Constants.UTF8);
            Configs configs = JsonMapper.nonDefaultMapper().getBean(Application.getConfigFileInputStream(), Configs.class);
            return Observable.just(configs);
        }).subscribeOn(Schedulers.io()).observeOn(JavaFxScheduler.platform()).subscribe((configs) -> {
            this.configs = configs;
        });
    }

    public StackPane getRootView() {
        return (StackPane) dashboard.getView();
    }

    public StackPane getRootContentView() {
        return dashboard.getRealPresenter().getContent();
    }

    public HBox getFooterView() {
        return dashboard.getRealPresenter().getFooter();
    }


    public Replacement replacement() {
        return replacement;
    }


    /**
     * get i18n string by key
     *
     * @param key
     * @return
     */
    public static String getString(String key) {
        final ResourceBundle bundle = SmartDataBus.get().getBundle();
        if (bundle.containsKey(key)) {
            return bundle.getString(key);
        }
        return key;
    }

    /**
     * get i18n string list by keys
     *
     * @param keys
     * @return
     */
    public static List<String> getString(String... keys) {
        List<String> result = Lists.newArrayList();
        for (String key : keys) {
            result.add(getString(key));
        }
        return result;
    }
}
